/******************************************************************************
* 	Copyright (c) 2007-2008 All rights reserved
*		Asemantics S.r.l
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer. 
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution,
*    if any, must include the following acknowledgment:
*       "This product includes software developed by 
*	 Asemantics S.r.l."
*    Alternately, this acknowledgment may appear in the software itself,
*    if and wherever such third-party acknowledgments normally appear.
*
* 4. All advertising materials mentioning features or use of this software
*    must display the following acknowledgement:
*    This product includes software developed by Asemantics S.r.l.
*    the Semantic Web company, Rome, London, Leiden and its contributors. 
*
* 5. Neither the name of the company nor the names of its contributors
*    may be used to endorse or promote products derived from this software
*    without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Author: Andrea Marchesini - baku@asemantics.com
*
******************************************************************************/

#include <log2html.h>

#include <configure.h>
#include <analyze.h>
#include <html.h>
#include <dot.h>

static gint log_sort_func (struct log_istance_t *a, struct log_istance_t *b);

/* MAIN *********************************************************************/
int
main (int argc, char **argv)
{
  struct data_t *data;
  GError *error = NULL;
  GIOChannel *io;
  guint numb = 0;
  GList *list;

  /* Options: */
  if (!(data = configure_init (argc, argv, &error)))
    {
      g_fprintf (stderr, "Option error: %s\n", error->message);
      g_error_free (error);
      return 1;
    }

  /* Opening the log file: */
  if (!(io = g_io_channel_new_file (data->logfile, "r+", &error)))
    {
      g_fprintf (stderr, "Error opening the file '%s': %s\n", data->logfile,
		 error->message);
      configure_free (data);
      g_error_free (error);
      return 1;
    }

  /* For any single line... */
  while (1)
    {
      GIOStatus status;
      gchar *line;
      gsize length, last;

      status = g_io_channel_read_line (io, &line, &length, &last, &error);

      if (status == G_IO_STATUS_EOF)
	break;

      if (status == G_IO_STATUS_ERROR)
	{
	  g_fprintf (stderr, "Error reading the file '%s': %s\n",
		     data->logfile, error->message);
	  g_error_free (error);
	  break;
	}

      if (status == G_IO_STATUS_AGAIN)
	continue;

      line[last] = 0;
      numb++;

      /* analyze the line: */
      if (analyze (data, line, last, &error) == FALSE)
	{
	  g_fprintf (stderr, "Error analyzing the line %d: %s\n", numb,
		     error->message);
	  g_error_free (error);
	  error = NULL;
	}

      g_free (line);
    }

  /* Close the file: */
  g_io_channel_shutdown (io, FALSE, NULL);
  g_io_channel_unref (io);

  if (error)
    goto quit;

  /* Initialize the html stuffs: */
  html_init (data);

  numb = 0;

  /* For any execution of the controller: */
  for (list = data->logs; list; list = list->next)
    {
      struct log_t *log = list->data;
      gchar *basename;

      log->istances =
	g_list_sort (log->istances, (GCompareFunc) log_sort_func);

      basename = g_strdup_printf ("%d", numb++);

      /* Dot: */
      if (dot (data, log, basename, &error) == FALSE)
	{
	  g_fprintf (stderr, "Error executing dot (graphviz): %s\n",
		     error->message);
	  g_error_free (error);
	  g_free (basename);
	  goto quit;
	}

      /* HTML pages: */
      if (html_log (data, log, basename, &error) == FALSE)
	{
	  g_fprintf (stderr, "Error creating the html pages: %s\n",
		     error->message);
	  g_error_free (error);
	  g_free (basename);
	  goto quit;
	}

      g_free (basename);
    }

  /* HTML index: */
  if (html_index (data, &error) == FALSE)
    {
      g_fprintf (stderr, "Error creating the html pages: %s\n",
		 error->message);
      g_error_free (error);
      goto quit;
    }

quit:
  configure_free (data);
  return error == NULL ? 0 : 1;
}

/* LOG SYSTEM OF GLIB *******************************************************/
GQuark
log2html_error_quark (void)
{
  static GQuark q = 0;

  if (!q)
    q = g_quark_from_static_string ("log2html-error-quark");

  return q;
}

/* SORTING FUNCTION *********************************************************/

static gint
log_sort_func (struct log_istance_t *a, struct log_istance_t *b)
{
  if (a->pid < b->pid)
    return -1;

  if (a->pid > b->pid)
    return 1;

  if (a->type == ISTANCE_BORN)
    return -1;

  if (b->type == ISTANCE_BORN)
    return 1;

  if (a->type == ISTANCE_DIED)
    return 1;

  if (b->type == ISTANCE_DIED)
    return -1;

  return 0;
}

/* EOF */
